package ihm;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.DebugGraphics;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import javax.swing.JPopupMenu;
import javax.swing.JToolBar;

import javax.swing.Timer;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;

import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

import javax.swing.filechooser.FileNameExtensionFilter;

import kernel.Bagage;
import kernel.Chariot;
import kernel.ConfigLoader;
import kernel.Noeud;
import kernel.Rail;
import kernel.Simulation;
import kernel.TapisRoulant;
import kernel.Toboggan;

import vue.VueElement;
import vue.VueRail;
import vue.VueSimulation;
import vue.VueTapisRoulant;
import vue.VueToboggan;

public class SGBag extends JFrame {
    private BorderLayout layoutMain = new BorderLayout();
    private JPanel panelCenter = new JPanel();
    private JMenuBar menuBar = new JMenuBar();
    private JMenu menuFile = new JMenu();
    private JMenuItem menuFileExit = new JMenuItem();
    private JMenu menuHelp = new JMenu();
    private JMenuItem menuHelpAbout = new JMenuItem();
    private JLabel statusBar = new JLabel();
    private Simulation simulation = null;
    private VueSimulationPanel panelVueSimulation = new VueSimulationPanel();
    private JPanel panelGraphe = new JPanel();
    private JButton buttonDetail = new JButton();
    private SGBag_BagageDetail sGBag_BagageDetail = new SGBag_BagageDetail();
    private JButton buttonStart_Pause = new JButton();
    private JToolBar toolBar = new JToolBar();
    private JButton buttonImport = new JButton();
    private JButton buttonExport = new JButton();
    private JButton buttonSwitchMode = new JButton();
    private JPopupMenu popupMenuGraphe = new JPopupMenu();
    private JButton buttonCreateBagage = new JButton();
    private SGBag_NewBagageDialog sGBag_NewBagageDialog = new SGBag_NewBagageDialog();
    private Icon iconPlay = new ImageIcon("src\\ihm\\icon\\play.png");
    private Icon iconPause = new ImageIcon("src\\ihm\\icon\\pause.png");
    private int LAPSE_TEMPS = 100;//millisecondes; 
    private transient ActionListener taskPerformer = new ActionListener() {

        public void actionPerformed(ActionEvent evt) {
            //simulation.Avancer();
            simulation.top_Horloge();
            panelVueSimulation.redessiner();
            sGBag_BagageDetail.printDetail();
            System.out.println("VueElement : "+panelVueSimulation.getVueSimulation().getVueElementCount());
        }
    };
    private Timer bouleTimer = new Timer(LAPSE_TEMPS, taskPerformer);
    
    public SGBag() {
        try {
            jbInit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public void startAvancer() {
        bouleTimer.start();
    }

    public void stopAvancer() {
        bouleTimer.stop();
    }

    private void jbInit() throws Exception {
        this.setJMenuBar( menuBar );
        this.getContentPane().setLayout( layoutMain );
        panelCenter.setLayout(new BorderLayout());
        menuBar.setFocusCycleRoot(true);
        this.setSize(new Dimension(727, 538));
        this.setBounds(new Rectangle(10, 10, 727, 600));
        this.addComponentListener(new ComponentAdapter() {
                public void componentResized(ComponentEvent e) {
                    this_componentResized(e);
                }
            });
        menuFile.setText( "Fichier" );
        menuFile.setDisplayedMnemonicIndex(0);
        menuFileExit.setText( "Quitter SGBag" );
        menuFileExit.setDisplayedMnemonicIndex(0);
        menuFileExit.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent ae ) { fileExit_ActionPerformed( ae ); } } );
        menuHelp.setText( "Aide" );
        menuHelpAbout.setText( "A propos de SGBag" );
        menuHelpAbout.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent ae ) { helpAbout_ActionPerformed( ae ); } } );
        statusBar.setText( "" );
        panelVueSimulation.setBorder(BorderFactory.createTitledBorder(""));
        panelVueSimulation.setBackground(Color.white);
        panelVueSimulation.setComponentPopupMenu(popupMenuGraphe);
        panelVueSimulation.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    panelVueSimulation_mouseClicked(e);
                }
            });
        panelGraphe.setBorder(BorderFactory.createTitledBorder("Graphe Synaptique"));
        panelGraphe.setLayout(new BorderLayout());
        buttonDetail.setIcon(new ImageIcon("src\\ihm\\icon\\detail.png"));
        buttonDetail.setFont(new Font("Cambria", 0, 12));
        buttonDetail.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    ButtonDetail_mouseClicked(e);
                }
            });
        buttonDetail.setToolTipText("Detail");
        sGBag_BagageDetail.setSize(new Dimension(230, 400));
        this.buttonStart_Pause.setIcon(iconPlay);
        this.buttonStart_Pause.setToolTipText("Start");
        buttonStart_Pause.setFont(new Font("Cambria", 0, 12));
        buttonStart_Pause.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    buttonStart_Pause_mouseClicked(e);
                }
            });
        toolBar.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
        buttonImport.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
        buttonImport.setBorderPainted(true);
        buttonExport.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
        buttonExport.setBorderPainted(true);
        buttonExport.setEnabled(false);
        buttonSwitchMode.setText(" A ");
        buttonSwitchMode.setToolTipText("Switch to Auto mode, current mode is Manuel");
        buttonSwitchMode.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
        buttonSwitchMode.setBorderPainted(true);
        buttonSwitchMode.setFont(new Font("Consolas", 1, 14));
        buttonSwitchMode.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    buttonSwitchMode_mouseClicked(e);
                }
            });
        popupMenuGraphe.setLabel("PopupMenuGraphe");
        popupMenuGraphe.setInvoker(panelVueSimulation);
        buttonCreateBagage.setIcon(new ImageIcon("src\\ihm\\icon\\add_bagage.png"));
        buttonCreateBagage.setToolTipText("Add Bagage");
        buttonCreateBagage.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    buttonCreateBagage_mouseClicked(e);
                }
            });
        menuFile.add(menuFileExit);
        menuBar.add(menuFile);
        menuHelp.add(menuHelpAbout);
        menuBar.add(menuHelp);
        this.getContentPane().add(statusBar, BorderLayout.SOUTH);
        this.getContentPane().add(panelCenter, BorderLayout.CENTER);
        buttonImport.setIcon(new ImageIcon("src\\ihm\\icon\\folder.jpg"));
        buttonImport.setToolTipText("Import Configuration File");
        buttonImport.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    buttonImport_mouseClicked(e);
                }
            });
        buttonExport.setIcon(new ImageIcon("src\\ihm\\icon\\save.jpg"));
        buttonExport.setToolTipText("Save Configuration");
        panelGraphe.add(panelVueSimulation, BorderLayout.CENTER);
        panelCenter.add(panelGraphe, BorderLayout.CENTER);
        toolBar.add(buttonImport, null);
        toolBar.add(buttonExport, null);
        toolBar.add(buttonSwitchMode, null);
        toolBar.add(buttonCreateBagage, null);
        toolBar.add(buttonStart_Pause, null);
        toolBar.add(buttonDetail, null);
        panelCenter.add(toolBar, BorderLayout.NORTH);

        sGBag_NewBagageDialog.setSGBag(this);
        sGBag_BagageDetail.setSGBag(this);
    }

    void fileExit_ActionPerformed(ActionEvent e) {
        System.exit(0);
    }

    void helpAbout_ActionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(this, new SGBag_AboutBoxPanel1(), "About", JOptionPane.PLAIN_MESSAGE);
    }

    private void ButtonDetail_mouseClicked(MouseEvent e) {
        if(sGBag_BagageDetail.isVisible()) {
            sGBag_BagageDetail.setVisible(false);
        }
        else{
            sGBag_BagageDetail.setLocation((int)this.getLocation().getX()+this.getWidth(), (int)this.getLocation().getY());
            sGBag_BagageDetail.setVisible(true);
        }
        menuBar.updateUI();
    }

    private void buttonStart_Pause_mouseClicked(MouseEvent e) {
        // arreter la simualtion et commencer la simulation
        if (simulation == null) return;
        if (simulation.isPause()){
            this.startAvancer();
            simulation.setPause(false);
            this.buttonStart_Pause.setIcon(iconPause);
            this.buttonStart_Pause.setToolTipText("Pause");
        }
        else{
            this.stopAvancer();
            simulation.setPause(true);
            this.buttonStart_Pause.setIcon(iconPlay);
            this.buttonStart_Pause.setToolTipText("Start");
        }
    }

    private void popupMenuGraphe_componentShown(ComponentEvent e) {
        popupMenuGraphe.setVisible(false);
    }

    private void popupMenuGraphe_popupMenuWillBecomeVisible(PopupMenuEvent e) {
        popupMenuGraphe.setVisible(false);
    }

    private void panelVueSimulation_mouseClicked(MouseEvent e) {
        /*
         * retouver l'object selectionne
         * et de le traiter dans differents cas
         */

        if(panelVueSimulation.getVueSimulation() == null) return;
        VueElement vE = panelVueSimulation.getVueSimulation().SelectElement(e.getX(), e.getY());
        if(vE != null) {
            // si l'object est trouve
            if(this.sGBag_NewBagageDialog.isSelectNoeudMode()){
                /*
                 * lorsqu'on est a l'etat de creation de bagage
                 * on passe cette object a sGBag_NewBagageDialog 
                 * si il correspond a un tapisRoulant ou un toboggan
                 */
                if(vE instanceof VueTapisRoulant){
                    this.sGBag_NewBagageDialog.selectNoeud(((VueTapisRoulant)vE).getTapisRoulant());
                }
                else if(vE instanceof VueToboggan){
                    this.sGBag_NewBagageDialog.selectNoeud(((VueToboggan)vE).getToboggan());
                }
                else{
                    return;
                }
            }
            else if (this.sGBag_BagageDetail.isSelectRailMode()){
                /*
                 * lorsqu'on est a l'etat de pilotage de chariot
                 * on passe cette object a sGBag_BagageDetail 
                 * si il correspond a un rail
                 */
                if (vE instanceof VueRail){
                    this.sGBag_BagageDetail.selectRail(((VueRail)vE).getRail());
                }
                else{
                    return;
                }
            }
            else{
                /*
                 * lorsqu'on est a l'etat normal
                 * on passe cette object a sGBag_BagageDetail 
                 * pour qu'il affiche ses informations
                 */
                sGBag_BagageDetail.setVueElement(vE);
                sGBag_BagageDetail.printDetail();
            }
        }

        panelVueSimulation.redessiner();
    }

    private void buttonCreateBagage_mouseClicked(MouseEvent e) {
        /*
         * afficher l'ecran de la creation de bagage sGBag_NewBagageDialog
         */
        sGBag_NewBagageDialog.setLocation((int)this.getLocation().getX()+this.getWidth(), (int)this.getLocation().getY()+sGBag_BagageDetail.getHeight());
        sGBag_NewBagageDialog.setVisible(true);
    }

    public void setSGBag_NewBagageDialog(SGBag_NewBagageDialog sGBag_NewBagageDialog) {
        this.sGBag_NewBagageDialog = sGBag_NewBagageDialog;
    }

    public SGBag_NewBagageDialog getSGBag_NewBagageDialog() {
        return sGBag_NewBagageDialog;
    }

    private void this_componentResized(ComponentEvent e) {
        /*
         * modifier la raille de la vue lorque'on a modifier la taille de l'ecran
         */
        VueSimulation vS = panelVueSimulation.getVueSimulation();
        if (vS != null) {
            vS.setLargeurVueZone(panelVueSimulation.getHeight());
            vS.setLongueurVueZone(panelVueSimulation.getWidth());
        }
    }

    private void buttonSwitchMode_mouseClicked(MouseEvent e) {
        /*
         * Alterner le mode de la simulation
         */
        if (simulation == null) return;
        if (simulation.isPiloteAutomatique()){
            simulation.setPiloteAutomatique(false);
            buttonSwitchMode.setText(" A ");
            buttonSwitchMode.setToolTipText("Switch to Auto mode, current mode is Manuel");
        }
        else{
            simulation.setPiloteAutomatique(true);
            buttonSwitchMode.setText(" M ");
            buttonSwitchMode.setToolTipText("Switch to manuel mode, current mode is Auto");
        }
    }

    public void setSimulation(Simulation simulation) {
        this.simulation = simulation;
    }

    public Simulation getSimulation() {
        return simulation;
    }

    public void setPanelVueSimulation(VueSimulationPanel panelVueSimulation) {
        this.panelVueSimulation = panelVueSimulation;
    }

    public VueSimulationPanel getPanelVueSimulation() {
        return panelVueSimulation;
    }

    private void buttonImport_mouseClicked(MouseEvent e) {
        /*
         * importer le ficher XML et de creer la simulation correspond
         */
        JFileChooser chooser = new JFileChooser();
        chooser.setDialogTitle("Choose a XML Configuration file");
        FileNameExtensionFilter filter = new FileNameExtensionFilter(
          "XML Configuration", "xml");
        chooser.setFileFilter(filter);
        chooser.showOpenDialog(null);
        File file = chooser.getSelectedFile();
        if (file != null){
            simulation = ConfigLoader.chargerConfiguration(file, panelVueSimulation);
            //panelVueSimulation.setSimulation(simulation);
            this.stopAvancer();
            simulation.setPause(true);
        }
    }
}
